package util

import (
	"encoding/json"

	sourceAST "github.com/graphql-go/graphql/language/ast"
	"github.com/graphql-go/graphql/language/parser"
	"github.com/graphql-go/graphql/language/visitor"
)

func GetGraphqlFunc(body []byte) ([]string, error) {
	funcs := make([]string, 0)
	var req struct {
		Query     string      `json:"query"`
		Variables interface{} `json:"variables"`
	}

	if err := json.Unmarshal(body, &req); err != nil {
		return funcs, err
	}

	fields, err := visitFields(req.Query)
	if err != nil {
		return funcs, err
	}

	for _, f := range fields {
		funcs = append(funcs, f.Name.Value)
	}

	return funcs, nil
}

func visitFields(query string) ([]*sourceAST.Field, error) {
	var fields []*sourceAST.Field
	ast, err := parser.Parse(parser.ParseParams{Source: query})
	if err != nil {
		return fields, err
	}
	v := &visitor.VisitorOptions{
		Enter: func(p visitor.VisitFuncParams) (string, interface{}) {
			if node, ok := p.Node.(*sourceAST.Field); ok {
				if node.SelectionSet == nil {
					return visitor.ActionNoChange, nil
				}

				fields = append(fields, node)
			}
			return visitor.ActionNoChange, nil
		},
	}
	visitor.Visit(ast, v, nil)
	return fields, nil
}
